﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Microsoft.Office.Interop.Word;
using ReportWizard.DataAccess;
using ReportWizard.Entities;
using ReportWizard.Interface;
using ReportWizard.Properties;
using Word = Microsoft.Office.Interop.Word;
using WordApplication =  Microsoft.Office.Interop.Word._Application;

namespace ReportWizard.Helpers
{
    public class MsWord : IDisposable
    {
        private static WordApplication _wordApp;

        private readonly bool _isOpenDocument;

        public MsWord(bool isOpenDocument)
        {
            _isOpenDocument = isOpenDocument;
        }

        public void CreateDocument()
        {
            Report currentReport = Globals.CurrentReport;
            if (currentReport != null)
            {
                try
                {
                    string pathTemplateFileName = Path.Combine(Perferences.PathTemplateFile,
                                                               currentReport.ReportTemplate.FileName);

                    FileStream fileStream = new FileStream(pathTemplateFileName, FileMode.Create, FileAccess.ReadWrite);
                    using (BinaryWriter binWriter = new BinaryWriter(fileStream))
                    {
                        binWriter.Write(currentReport.ReportTemplate.Template);
                        binWriter.Close();
                    }

                    if (File.Exists(pathTemplateFileName))
                    {
                        string pathReportFileName = Path.Combine(Perferences.PathReportFile, currentReport.Name);

                        _wordApp = new Word.Application();

                        _Document oDoc = GetDoc(pathTemplateFileName);
                        oDoc.SaveAs(pathReportFileName);
                        oDoc.Close();

                        _wordApp.Quit();

                        File.Delete(pathTemplateFileName);

                        if (_isOpenDocument)
                            Process.Start(pathReportFileName);
                        else
                        {
                            ShowMessage.Info(string.Format("{0}\n{1}", Resources.FileSuccessfullyCreated,
                                                           pathReportFileName));
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.WriteLog(ex);
                }
            }
        }

        public static List<string> GetBookmarks(string path)
        {
            try
            {
                _wordApp = new Word.Application();

                _Document oDoc = _wordApp.Documents.Add(path);
                if (oDoc.Bookmarks.Count != 0)
                {
                    List<string> st = new List<string>();
                    for (int i = 0; i < oDoc.Bookmarks.Count; i++)
                    {
                        object index = i + 1;
                        st.Add(oDoc.Bookmarks.get_Item(ref index).Name);
                    }
                    oDoc.Close();
                    return st;
                }
                return null;
            }
            catch(Exception ex)
            {
                Logger.WriteLog(ex);
                return null;
            }
            finally
            {
                _wordApp.Quit();
            }
        }

        private static _Document GetDoc(string path)
        {
            try
            {
                _Document oDoc = _wordApp.Documents.Add(path);
                SetTemplate(oDoc);
                return oDoc;
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
                return null;
            }
        }

        private static void SetTemplate(Word._Document oDoc)
        {
            try
            {
                Object myTrue = true;

                var textBookmarks = Globals.CurrentReport.Fields.Where(i => i.Key is WordBookmark && ((WordBookmark)i.Key).IsTextBookmark);
                foreach (KeyValuePair<IBookmark, ReportBaseObject> textBookmark in textBookmarks)
                {
                    oDoc.Bookmarks[textBookmark.Key.Name].Range.Text = string.Format(@"{0}", textBookmark.Value.Name);
                }

                var bookmarkGroups = Globals.CurrentReport.Fields.Where(i => i.Key is BookmarkGroup);
                foreach (KeyValuePair<IBookmark, ReportBaseObject> bookmarkGroup in bookmarkGroups)
                {
                    var bookmarks = ((BookmarkGroup) bookmarkGroup.Key).GroupBookmarks;
                    foreach (WordBookmark wordBookmark in bookmarks)
                    {
                        oDoc.Bookmarks[wordBookmark.Name].Range.Text = string.Format(@"{0}", bookmarkGroup.Value.Name);
                    }
                }

                var imageBookmarks = Globals.CurrentReport.Fields.Where(i => i.Key is WordBookmark && !((WordBookmark)i.Key).IsTextBookmark);
                foreach (KeyValuePair<IBookmark, ReportBaseObject> imageBookmark in imageBookmarks)
                {
                    Object imgBookmark = imageBookmark.Key.Name;
                    Object myImageRange = oDoc.Bookmarks.get_Item(ref imgBookmark).Range;

                    var photoSet =
                        Globals.CurrentReport.PhotoCollection.Where(
                            i => i.BookmarkId == Convert.ToInt32(imageBookmark.Key.Id)).FirstOrDefault();

                    if (photoSet != null)
                    {
                        var photos = photoSet.Photos.Where(i => i.Checked).Reverse();
                        foreach (ReportImageFile photo in photos)
                        {
                            InlineShape imageShape = oDoc.InlineShapes.AddPicture(photo.FilePath, ref myTrue, ref myTrue, ref myImageRange);
                            imageShape.Range.Font.Bold = 0;
                            imageShape.Range.Font.Size = 10;
                            imageShape.Range.InsertAfter(string.Format("\n{0}\n", photo.Description));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
            }
            
        } 

        public void Dispose()
        {
            if (_wordApp != null)
            {
                _wordApp.Quit();
            }
        }
    }
}
